#include "flash.h"
#include "log.h"
#include "bsp_delay.h"
// 擦除函数
MI_BOOL n32_flash_erase(MI_U32 start_addr, MI_U32 end_addr)
{
    int page_num = 0; 
    FLASH_Unlock();
    /* erase the flash pages */

    while(start_addr < end_addr)
    {
        page_num = (start_addr - N32_FLASH_BASE) / FLASH_PAGE_SIZE;
        if (FLASH_EOP != FLASH_One_Page_Erase(page_num * FLASH_PAGE_SIZE))
        {
            Max_Info("Flash EraseOnePage Error. Please Deal With This Error Promptly\r\n");
            FLASH_Lock();
            return MI_FALSE;
        }
        start_addr += FLASH_PAGE_SIZE;
    }

    FLASH_Lock();
    return MI_TRUE;
}

// 写函数
MI_BOOL n32_flash_write(MI_U32 dest_addr, MI_U8 *src, MI_U32 Len)
{
    MI_U32 i = 0;

    FLASH_Unlock();

    for(i = 0; i < Len; i += 4)
    {
        /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
        be done by byte */
        if(FLASH_EOP == FLASH_Word_Program((MI_U32)(dest_addr+i), *(uint32_t*)(src+i)))
        {
            /* Check the written value */
            if(*(uint32_t *)(src + i) != *(uint32_t*)(dest_addr+i))
            {
                /* Flash content doesn't match SRAM content */
                FLASH_Lock();            
                return -1;
            }
        }
        else
        {
            FLASH_Lock();            
            /* Error occurred while writing data in Flash memory */
            return -1;
        }
    }
    FLASH_Lock();            

    return 0;
}

// 读函数
MI_BOOL n32_flash_read(MI_U32 dest_addr, MI_U8* buff, MI_U32 Len)
{

    MI_U32 i;
    for(i = 0; i < Len; i++)
    {
        buff[i] = *(__IO MI_U8*)(dest_addr + i);
    }
    /* Return a valid address to avoid HardFault */
    return 0;
}

MI_BOOL copy_download_to_app(void)
{
    MI_U8 buffer[1024] = {0};  //每次从download读1K字节，然后写入1K
    MI_U8 w_count = 0;
    MI_U16 w_len = sizeof(buffer);
    MI_U16 app_size = APP_SIZE;

    w_count = app_size / w_len;
    // 将App区域擦除
    n32_flash_erase(APP_START_ADDRESS,APP_END_ADDRESS);
    max_print("w_count == %d\r\n",APP_SIZE);

    max_print("w_count == %d\r\n",w_len);

    max_print("w_count == %d\r\n",w_count);
    for (int i = 0;i < w_count;i++)
    {
        n32_flash_read(DOWNLOAD_START_ADDRESS + (w_len * i),buffer,w_len);
        SysTick_Delay_Ms(50);
        n32_flash_write(APP_START_ADDRESS + (w_len * i),buffer,w_len);
        
        max_print("update.............................%d [100] \r\n",((i+1) * 100 /w_count));
    }

    return MI_TRUE;
}
